package com.example.adminframework.common.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class Redis {

    @Autowired
    private RedisTemplate redisTemplate;

    // 删除key
    @SuppressWarnings("unchecked")
    public Boolean delete (String key){
        return redisTemplate.delete(key);
    }

    // 删除多个key
    @SuppressWarnings("unchecked")
    public void deleteKey (Collection keys){
        redisTemplate.delete(keys);
    }

    // 指定key的失效时间
    @SuppressWarnings("unchecked")
    public void expire(String key, long time){
        redisTemplate.expire(key,time, TimeUnit.MINUTES);
    }

    // 指定key的失效时间
    @SuppressWarnings("unchecked")
    public void expire(String key, long time, TimeUnit timeUnit){
        redisTemplate.expire(key,time, timeUnit);
    }

    // 根据key获取过期时间
    @SuppressWarnings("unchecked")
    public long getExpire(String key){
        Long expire = redisTemplate.getExpire(key);
        return expire;
    }

    //  判断key是否存在
    @SuppressWarnings("unchecked")
    public boolean hasKey(String key){
        return redisTemplate.hasKey(key);
    }

    /**
     * 获取所有key
     * @return
     */
    public Set<String> getAllKeys() {
        return redisTemplate.keys("*");
    }

    /**
     * 根据表达式获取key 可多可少～
     * @param pattern
     * @return
     */
    public Set<String> listKeyByPattern(String pattern) {
        return redisTemplate.keys(pattern);
    }

    /**
     * 批量获取数据
     * @param keys
     * @return
     */
    public List getDataByKeys(Collection keys) {
        return redisTemplate.opsForValue().multiGet(keys);
    }

    /**
     * string 类型添加数据
     * @param key
     * @param value
     */
    @SuppressWarnings("unchecked")
    public void setStrValue(String key, Object value) {
        setStrValue(key, value, null, null);
    }

    /**
     * string 类型添加数据 默认超时单位为分钟
     * @param key
     * @param value
     */
    @SuppressWarnings("unchecked")
    public void setStrValue(String key, Object value, Integer timeout, TimeUnit timeUnit) {
        if (timeout != null) {
            if (timeUnit == null) {
                timeUnit = TimeUnit.MINUTES;
            }
            redisTemplate.boundValueOps(key).set(value,timeout, timeUnit);
            return;
        }
        redisTemplate.boundValueOps(key).set(value);

    }

    /**
     * string 类型 获取数据
     * @param key
     */
    @SuppressWarnings("unchecked")
    public <T extends Object> T getStrValue(String key) {
        //1、通过redisTemplate设置值
        return (T)redisTemplate.boundValueOps(key).get();
    }

    /**
     * String类型 删除key
     * @param key
     * @return
     */
    @SuppressWarnings("unchecked")
    public Boolean deleteStrKey(String key) {
        return redisTemplate.delete(key);
    }

    /**
     * hash 类型添加
     * @param key
     * @param field
     * @param value
     */
    @SuppressWarnings("unchecked")
    public void setHashValue(String key, String field, Object value, Long time, TimeUnit timeUnit) {
        redisTemplate.boundHashOps(key).put(field, value);
        if (time != null) {
            if (timeUnit == null) {
                timeUnit = TimeUnit.MINUTES;
            }
            this.expire(key, time, timeUnit);
        }

    }

    /**
     * hash 类型添加
     * @param key
     * @param field
     * @param value
     */
    @SuppressWarnings("unchecked")
    public void setHashValue(String key, String field, Object value) {
        setHashValue(key, field, value, null, null);
    }

    /**
     * hash map类型添加
     * @param key
     * @param hashMap
     */
    @SuppressWarnings("unchecked")
    public void setHashValue(String key, Map<String, Object> hashMap, Long time, TimeUnit timeUnit) {
        redisTemplate.boundHashOps(key).putAll(hashMap);
        if (time != null) {
            if (timeUnit == null) {
                timeUnit = TimeUnit.MINUTES;
            }
            this.expire(key, time, timeUnit);
        }
    }

    /**
     * hash map类型添加
     * @param key
     * @param hashMap
     */
    @SuppressWarnings("unchecked")
    public void setHashValue(String key, Map<String, Object> hashMap) {
        setHashValue(key, hashMap, null, null);
    }

    /**
     * 获取所有hash keys
     * @param key
     */
    @SuppressWarnings("unchecked")
    public Set<String> getHashKeys(String key) {
        return redisTemplate.boundHashOps(key).keys();
    }

    /**
     * hash类型获取所有values
     * @param key
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T extends Object>List<T> getHashValues(String key) {
        List<T> values = redisTemplate.boundHashOps(key).values();
        return values;
    }

    /**
     * Hash类型获取具体值
     * @param key
     * @param field
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T extends Object> T getHashValue(String key, String field) {
        return (T)redisTemplate.boundHashOps(key).get(field);
    }

    /**
     * 获取Hash类型所有键值对
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> getHashValueMap(String key) {
        return redisTemplate.boundHashOps(key).entries();
    }

    /**
     * hash类型 根据key field删除
     * @param key
     * @param field
     */
    @SuppressWarnings("unchecked")
    public void deleteHashKey(String key, String field) {
        redisTemplate.boundHashOps(key).delete(field);
    }

    /**
     * hash类型  根据key删除
     * @param key
     */
    @SuppressWarnings("unchecked")
    public Boolean deleteHashKey(String key) {
        return redisTemplate.delete(key);
    }

    /**
     * hash类型 判断是否有值
     * @param key
     * @param field
     * @return
     */
    @SuppressWarnings("unchecked")
    public Boolean existHash(String key, String field) {
        return redisTemplate.boundHashOps(key).hasKey(field);
    }

    /**
     * set 类型添加数据
     * @param key
     * @param values
     */
    @SuppressWarnings("unchecked")
    public void setSetValue(String key, Collection values) {
        BoundSetOperations<String, Object> setKey = redisTemplate.boundSetOps(key);
        setKey.add(values);
    }

    /**
     * set 类型获取数据
     * @param key
     * @return
     */
    @SuppressWarnings("unchecked")
    public Set<? extends Object> getSetValue(String key) {
        BoundSetOperations setKey = redisTemplate.boundSetOps(key);
        return setKey.members();
    }

    /**
     * set 类型 判断一个值 是否存在
     * @param key
     * @param value
     * @return
     */
    @SuppressWarnings("unchecked")
    public Boolean existSet(String key, Object value) {
        return redisTemplate.boundSetOps(key).isMember(value);
    }

    /**
     * set 类型 获取一个key的值长度
     * @param key
     * @return
     */
    @SuppressWarnings("unchecked")
    public Long getSetSize(String key) {
        return redisTemplate.boundSetOps(key).size();
    }

    /**
     * set 类型根据key删除values
     * @param key
     * @param values
     */
    @SuppressWarnings("unchecked")
    public void deleteSetValue(String key, Collection values) {
        redisTemplate.boundSetOps(key).remove(values);
    }

    /**
     * set 类型删除制定key
     * @param key
     * @return
     */
    @SuppressWarnings("unchecked")
    public Boolean deleteSetKey(String key) {
        return this.delete(key);
    }

    /**
     * list 类型 左添加数据
     * @param key
     * @param value
     */
    @SuppressWarnings("unchecked")
    public void setListLeftValue(String key, Object value) {
        redisTemplate.boundListOps(key).leftPush(value);
    }

    /**
     * list 类型 右添加数据
     * @param key
     * @param value
     */
    @SuppressWarnings("unchecked")
    public void setListRightValue(String key, Object value) {
        redisTemplate.boundListOps(key).rightPush(value);
    }

    /**
     * 将list 放入左侧缓存
     */
    @SuppressWarnings("unchecked")
    public void setListLeftList(String key, List<? extends Object> values) {
        redisTemplate.boundListOps(key).leftPushAll(values.toArray());
    }

    /**
     * 将list 放入右侧缓存
     */
    @SuppressWarnings("unchecked")
    public void setListRightList(String key, List<? extends Object> values) {
        redisTemplate.boundListOps(key).rightPushAll(values.toArray());
    }

    /**
     * list 获取数据
     * @param key
     * @param start
     * @param end
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<? extends Object> getListValues(String key, Integer start, Integer end) {
        return redisTemplate.boundListOps(key).range(start, end);
    }

    /**
     * list 左侧弹出一个元素
     * @param key
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T extends Object>T leftPopKey(String key) {
        return (T)redisTemplate.boundListOps(key).leftPop();
    }

    /**
     * list 右侧弹出一个元素
     * @param key
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T extends Object>T rightPopKey(String key) {
        return (T)redisTemplate.boundListOps(key).rightPop();
    }

    /**
     * list 根据索引获取一个数据
     * @param key
     * @param index
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T extends Object> T getListValueByIndex(String key, Long index) {
        return(T) redisTemplate.boundListOps(key).index(index);
    }

    /**
     * list 获取数据长度
     */
    @SuppressWarnings("unchecked")
    public Long getListValueSize(String key) {
        return redisTemplate.boundListOps(key).size();
    }

    /**
     * 根据索引替换数据
     * @param key
     * @param value
     * @param index
     */
    @SuppressWarnings("unchecked")
    public void updateListValueByIndex(String key, Object value, Long index) {
        redisTemplate.boundListOps(key).set(index, value);
    }

    /**
     * list 类型 移除count 个 value值
     * @param key
     * @param value
     * @param count
     */
    @SuppressWarnings("unchecked")
    public void deleteListValue(String key, Object value, Long count) {
        redisTemplate.boundListOps(key).remove(count, value);
    }

    /**
     * zset插入数据并设置分数
     */
    @SuppressWarnings("unchecked")
    public void setZsetValue(String key, Object value, Double score) {
        redisTemplate.boundZSetOps(key).add(value, score);
    }

    /**
     * zset 获取数据
     * @param key
     * @param start
     * @param end
     * @return
     */
    @SuppressWarnings("unchecked")
    public Set getZsetValues(String key, Long start, Long end) {
        return redisTemplate.boundZSetOps(key).range(start, end);
    }

    /**
     * 获取具体某一个数据的分数
     * @param key
     * @param value
     * @return
     */
    @SuppressWarnings("unchecked")
    public Double getZsetValueScore(String key, Object value) {
        return redisTemplate.boundZSetOps(key).score(value);
    }

    /**
     * 获取某一个key数据长度
     * @param key
     * @return
     */
    @SuppressWarnings("unchecked")
    public Long getZsetValueSize(String key) {
        return redisTemplate.boundZSetOps(key).size();
    }

    /**
     * zset 移除一个数据
     * @param key
     * @param value
     */
    @SuppressWarnings("unchecked")
    public void deleteZsetValue(String key, Object value) {
        redisTemplate.boundZSetOps(key).remove(value);
    }

    /**
     * zset 移除一个key
     * @param key
     */
    @SuppressWarnings("unchecked")
    public void deleteZsetKey(String key) {
        this.delete(key);
    }

}
